package de.slothsoft.wasbinich.swingclient.control;

import static de.slothsoft.wasbinich.core.WasBinIch.SUPPORTED_LANGUAGES;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import de.slothsoft.commons.swing.GridBagUtil;
import de.slothsoft.commons.swing.JToolBarManager;
import de.slothsoft.wasbinich.core.FullPicture;
import de.slothsoft.wasbinich.core.database.Database;
import de.slothsoft.wasbinich.core.database.DatabaseException;
import de.slothsoft.wasbinich.core.util.PictureUtil;
import de.slothsoft.wasbinich.core.validation.ValidationError;
import de.slothsoft.wasbinich.core.validation.ValidationUtil;
import de.slothsoft.wasbinich.swingclient.WasBinIchSwingClient;
import de.slothsoft.wasbinich.swingclient.control.TitlePanel.ScreenSwitcher;
import de.slothsoft.wasbinich.swingclient.res.Images;
import de.slothsoft.wasbinich.swingclient.res.Messages;

public class PicturePanel extends ChildPanel {

    private static final long serialVersionUID = -5644476984634609514L;

    private JPanel basePanel;

    private ImageControl sectionControl;
    private ImageControl bigPictureControl;

    private JButton deleteButton;
    private JTextField[] correctTextFields;
    private JTextArea[] descriptionTextAreas;

    private FullPicture picture;

    public PicturePanel(ScreenSwitcher screenSwitcher) {
	super(screenSwitcher);
    }

    @Override
    protected Component createControls() {
	this.basePanel = new JPanel();
	this.basePanel.setOpaque(true);
	this.basePanel.setLayout(new GridBagLayout());
	this.basePanel.setBackground(new Color(255, 255, 255, 127));
	this.basePanel.setBorder(BorderFactory.createTitledBorder(""));

	this.basePanel.add(createPicturePanel(), new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
		GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, GridBagUtil.DEFAULT_INSETS, 0, 0));

	this.correctTextFields = new JTextField[SUPPORTED_LANGUAGES.length];
	this.descriptionTextAreas = new JTextArea[SUPPORTED_LANGUAGES.length];
	int index = 0;
	int y = 1;
	for (Locale supportedLanguage : SUPPORTED_LANGUAGES) {
	    this.basePanel.add(
		    new JLabel(MessageFormat.format(Messages.getString("Picture.correctAnswer"),
			    supportedLanguage.getDisplayLanguage())
			    + ":"), GridBagUtil.labelDefaults(0, y));
	    this.correctTextFields[index] = new JTextField();
	    this.basePanel.add(this.correctTextFields[index], GridBagUtil.textFieldDefaults(1, y));

	    y++;

	    this.basePanel.add(
		    new JLabel(MessageFormat.format(Messages.getString("Picture.description"),
			    supportedLanguage.getDisplayLanguage())
			    + ":"), GridBagUtil.labelDefaults(0, y));
	    this.descriptionTextAreas[index] = new JTextArea();
	    this.basePanel.add(new JScrollPane(this.descriptionTextAreas[index]), GridBagUtil.textAreaDefaults(1, y));

	    y++;
	    index++;
	}

	return this.basePanel;
    }

    private Component createPicturePanel() {
	JPanel picturePanel = new JPanel();
	picturePanel.setOpaque(false);
	picturePanel.setLayout(new GridBagLayout());

	picturePanel.add(new JLabel(Messages.getString("Picture.section")), GridBagUtil.labelDefaults(0, 0));
	picturePanel.add(new JLabel(Messages.getString("Picture.bigPicture")), GridBagUtil.labelDefaults(1, 0));

	this.sectionControl = new ImageControl();
	picturePanel.add(this.sectionControl, GridBagUtil.textAreaDefaults(0, 1));

	this.bigPictureControl = new ImageControl();
	picturePanel.add(this.bigPictureControl, GridBagUtil.textAreaDefaults(1, 1));

	return picturePanel;
    }

    @Override
    protected void switchBack() {
	getScreenSwitcher().switchScreen(MainPanel.SCREEN_PICTURES);
    }

    public void setPicture(FullPicture newPicture) {
	setTitle(newPicture.toString());
	((TitledBorder) this.basePanel.getBorder()).setTitle(newPicture.toString());

	setImageToControl(this.sectionControl, newPicture.section);
	setImageToControl(this.bigPictureControl, newPicture.bigPicture);

	int index = 0;
	for (Locale supportedLanguage : SUPPORTED_LANGUAGES) {
	    this.correctTextFields[index].setText(newPicture.getCorrectAnswers(supportedLanguage));
	    this.descriptionTextAreas[index].setText(newPicture.getDescription(supportedLanguage));
	    index++;
	}
	this.picture = newPicture;
	this.basePanel.getParent().repaint();
	this.deleteButton.setEnabled(this.picture.id != null);
    }

    private void setImageToControl(ImageControl pictureControl, String imageData) {
	pictureControl.setPreferredSize(getImageResizeDimension());
	if (imageData != null) {
	    try {
		pictureControl.setImageData(imageData);
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	} else {
	    pictureControl.setIcon(null);
	}
    }

    private Dimension getImageResizeDimension() {
	Dimension resizeDimension = this.basePanel.getSize();
	resizeDimension.height = resizeDimension.width / 4;
	resizeDimension.width = resizeDimension.height;
	return resizeDimension;
    }

    @Override
    protected void fillToolbar(JToolBarManager manager) {
	super.fillToolbar(manager);
	manager.addSeparator();
	manager.add(Images.get(Images.TOOLBAR_SAVE), new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		savePicture();
	    }
	});
	this.deleteButton = manager.add(Images.get(Images.TOOLBAR_DELETE), new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		deletePicture();
	    }
	});
    }

    protected void deletePicture() {
	if (JOptionPane.showConfirmDialog(this, Messages.getString("Question.deletePicture.message"),
		Messages.getString("Question.deletePicture.title"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
	    try {
		Database.getInstance().getManagerBean().deletePicture(this.picture.id.longValue());
	    } catch (DatabaseException e) {
		WasBinIchSwingClient.handleException(e);
	    }
	    switchBack();
	}
    }

    protected void savePicture() {
	if (this.picture != null) {
	    FullPicture newPicture = this.picture.clone();
	    updatePictureFromControls(newPicture);
	    if (!isValid(newPicture))
		return;
	    if (this.picture.id == null) {
		try {
		    newPicture = Database.getInstance().getManagerBean().createPicture(newPicture);
		} catch (DatabaseException e) {
		    WasBinIchSwingClient.handleException(e);
		}
	    } else {
		FullPicture differences = PictureUtil.getDifferences(this.picture, newPicture);
		if (differences != null) {
		    differences.id = this.picture.id;
		    try {
			newPicture = Database.getInstance().getManagerBean().updatePicture(differences);
		    } catch (DatabaseException e) {
			WasBinIchSwingClient.handleException(e);
		    }
		}
	    }
	    setPicture(newPicture);
	}
    }

    private void updatePictureFromControls(FullPicture aPicture) {
	if (aPicture != null) {
	    aPicture.section = this.sectionControl.getImageData();
	    aPicture.bigPicture = this.bigPictureControl.getImageData();

	    int index = 0;
	    for (Locale supportedLanguage : SUPPORTED_LANGUAGES) {
		aPicture.setCorrectAnswers(supportedLanguage, this.correctTextFields[index].getText());
		aPicture.setDescription(supportedLanguage, this.descriptionTextAreas[index].getText());
		index++;
	    }
	}
    }

    private boolean isValid(FullPicture newPicture) {
	ValidationError error = ValidationUtil.getErrorMessage(newPicture);
	if (error != null) {
	    JOptionPane.showMessageDialog(this, Messages.getString(error), Messages.getString("Error.title"),
		    JOptionPane.ERROR_MESSAGE);
	}
	return error == null;
    }

}
